home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / Tool Chest / Development Platforms / AppsToGo / AppsToGo.src / DTS.StyleChat / Menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-18  |  14.3 KB  |  561 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        Menu.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1990-1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19.  
  20.  
  21. /*****************************************************************************/
  22.  
  23.  
  24.  
  25. #include "App.h"            /* Get the application includes/typedefs, etc.    */
  26. #include "App.defs.h"        /* Get various application definitions.            */
  27. #include "App.protos.h"        /* Get the prototypes for application.            */
  28.  
  29. #ifndef __DESK__
  30. #include <Desk.h>
  31. #endif
  32.  
  33. #ifndef __ERRORS__
  34. #include <Errors.h>
  35. #endif
  36.  
  37. #ifndef __FONTS__
  38. #include <Fonts.h>
  39. #endif
  40.  
  41. #ifndef __MEMORY__
  42. #include <Memory.h>
  43. #endif
  44.  
  45. #ifndef __MENUS__
  46. #include <Menus.h>
  47. #endif
  48.  
  49. #ifndef __TOOLUTILS__
  50. #include <ToolUtils.h>
  51. #endif
  52.  
  53. #ifndef __UTILITIES__
  54. #include "Utilities.h"
  55. #endif
  56.  
  57.  
  58.  
  59. /*****************************************************************************/
  60.  
  61.  
  62.  
  63. extern Boolean    gQuitApplication;
  64. extern Boolean    gHasAppleEvents;
  65. extern OSType    gAppWindowType;
  66.  
  67. extern Boolean    gLowOnMem;
  68.  
  69. static short    NewFontSize(short size);
  70.  
  71.  
  72.  
  73. /*****************************************************************************/
  74. /*****************************************************************************/
  75.  
  76.  
  77.  
  78. /* •• Called by DTS.Lib..framework. •• */
  79.  
  80. /* Adjust the menu items.  We allow the DTS.Lib framework to do most of the work
  81. ** for us.  It will walk the menubar, and for each menu in the menubar, it will
  82. ** disable all of the menu items and then call the application at either
  83. ** AdjustMenuItems() (for document and palette windows, or for the no-window case),
  84. ** or DialogAdjustMenuItems() (for modal dialogs).  The application's job is to then
  85. ** turn on menu items that should be enabled to match the current application state.
  86. ** The initial Wannabe code for AdjustMenuItems() calls DoAdjustFileMenu() for the
  87. ** file menu, and DoAdjustEditMenu() for the edit menu.  Any other menus that may
  88. ** be added to Wannabe have all menu items enabled.  This allows menus to be added
  89. ** to the running version of Wannabe and allows them to actually do something.
  90. ** If the top-most window is a dialog, then all menus are disabled except for the
  91. ** edit menu.  Various items in the edit menu are enabled, depending on if there
  92. ** is an active TextEdit control, and what is in the clipboard. */
  93.  
  94. #pragma segment Menu
  95. void    DoAdjustMenus(void)
  96. {
  97.     if (DoAdjustMBARMenus(FrontWindow(), rMenuBar))
  98.         DrawMenuBar();
  99. }
  100.  
  101.  
  102.  
  103. /*****************************************************************************/
  104.  
  105.  
  106.  
  107. /* This is called when an item is chosen from the menu bar (after calling
  108. ** MenuSelect or MenuKey).  It performs the right operation for each command.
  109. ** It is good to have both the result of MenuSelect and MenuKey go to one
  110. ** routine like this to keep everything organized. */
  111.  
  112. #pragma segment Menu
  113. Boolean    DoMenuCommand(short menuID, short menuItem)
  114. {
  115.     short            undoDepth, numUndos, saveMode, daRefNum, mode, size;
  116.     Str255            str;
  117.     FileRecHndl        frHndl, newFrHndl;
  118.     WindowPtr        window;
  119.     TEHandle        te;
  120.     OSErr            err;
  121.     Boolean            handled;
  122.     TEHandle        teHndl;
  123.     TextStyle        styl;
  124.     MenuHandle        menu;
  125.     static Style    stylVal[] = {0, 0, 0, 1, 2, 4, 8, 16, 32, 64};
  126.  
  127.     handled = true;
  128.  
  129.     if (window = FrontWindow())
  130.         frHndl = (FileRecHndl)GetWRefCon(window);
  131.             /* frHndl is valid only if it is one of our windows. */
  132.  
  133.     switch (menuID) {
  134.  
  135.         case mApple:
  136.             switch (menuItem) {
  137.                 case kStdAbout:        /* Bring up alert for About. */
  138.                     NewDocumentWindow(nil, 'ABOT', false);
  139.                     break;
  140.                 default:            /* All non-About items in this menu are DAs. */
  141.                     GetItem(GetMHandle(mApple), menuItem, str);
  142.                     daRefNum = OpenDeskAcc(str);
  143.                     break;
  144.             }
  145.             break;
  146.  
  147.         case mFile:
  148.             switch (menuItem) {
  149.                 case kStdNew:
  150.                     if (err = NewDocumentWindow(nil, gAppWindowType, true))
  151.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  152.                     break;
  153.                 case kStdOpen:
  154.                     err = OpenDocumentWindow(&frHndl, nil, fsRdWrPerm);
  155.                     if ((err) && (err != userCanceledErr))
  156.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  157.                     break;
  158.                 case kStdClose:
  159.                     if (IsAppWindow(window)) {
  160.                         if (window = FrontWindowOfType(kwIsDocument, true))
  161.                             DisposeOneWindow(window, kClose);
  162.                     }
  163.                     else
  164.                         DisposeOneWindow(window, kClose);        /* Dispose of DA window. */
  165.                     break;
  166.                 case kStdSave:
  167.                 case kStdSaveAs:
  168.                     saveMode = (menuItem == kStdSave) ? kSave : kSaveAs;
  169.                     if ((*frHndl)->fileState.refNum == kInvalRefNum)
  170.                         saveMode = kSaveAs;
  171.                     err = SaveDocument(frHndl, window, saveMode);
  172.                     if ((err) && (err != userCanceledErr))
  173.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  174.                     break;
  175.                 case kDuplicate:
  176.                     err = DuplicateDocument(frHndl, &newFrHndl);
  177.                     if (!err) {
  178.                         err = DoNewWindow(newFrHndl, nil, FrontWindow(), (WindowPtr)-1);
  179.                         if (err)
  180.                             DisposeDocument(newFrHndl);
  181.                     }
  182.                     if (err)
  183.                         CenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  184.                     break;
  185.                 case kStdPageSetup:
  186.                     DoSetCursor(&qd.arrow);
  187.                     PresentStyleDialog(frHndl);
  188.                     break;
  189.                 case kStdPrint:
  190.                     DoSetCursor(&qd.arrow);
  191.                     err = noErr;
  192.                     if (!(*frHndl)->d.doc.fhInfo.printRecValid)
  193.                         err = PresentStyleDialog(frHndl);
  194.                     if (!err) {
  195.                         err = PrintDocument(frHndl, true, true);
  196.                         PrintDocument(nil, false, false);
  197.                     }
  198.                     if ((err) && (err != userCanceledErr))
  199.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  200.                     break;
  201.                 case kStdQuit:
  202.                     gQuitApplication = DisposeAllWindows();
  203.                     break;
  204.                 default:
  205.                     handled = false;
  206.                     break;
  207.             }
  208.             break;
  209.  
  210.         case mEdit:            /* Call SystemEdit for DA editing & MultiFinder. */
  211.             if (menuItem == kStdViewHier) {
  212.                 handled = false;
  213.                 break;
  214.             }
  215.             if (IsAppWindow(window)) {
  216.                 switch (menuItem) {
  217.                     case kStdUndo:
  218.                     case kStdRedo:
  219.                     case kStdCut:
  220.                     case kStdCopy:
  221.                     case kStdPaste:
  222.                     case kStdClear:
  223.                         switch ((*frHndl)->fileState.sfType) {
  224.                                 /* This is written with the assumption that document types
  225.                                 ** that demand specific code will be added.  The below “if”
  226.                                 ** illustrates how to handle the edit menu for windows that
  227.                                 ** have an active TextEdit control.  The “else” shows a typical
  228.                                 ** undo/redo scenario for applications that are using the
  229.                                 ** hierarchical document package.  The clipboard features
  230.                                 ** are of course document-dependent, so a sample hasn't been
  231.                                 ** implemented here.  For a sample, see DTS.Draw. */
  232.                             default:
  233.                                 if (te = CTEFindActive(window)) {
  234.                                     if ((*te)->viewRect.left < -8192)
  235.                                         BeginFrame(window);
  236.                                     else
  237.                                         BeginContent(window);
  238.                                     if (menuItem == kStdUndo)
  239.                                         CTEUndo();
  240.                                     else
  241.                                         CTEClipboard(menuItem - kStdCut + 2);
  242.                                     EndContent(window);
  243.                                 }
  244.                                 else {
  245.                                     if (menuItem <= kStdRedo) {
  246.                                         if (!UnmapMItem(mEdit, kStdUndo)) {
  247.                                             GetUndoInfo(frHndl, &undoDepth, &numUndos);
  248.                                             DoUndoTask((*frHndl)->d.doc.root, 1 - undoDepth, true);
  249.                                         }
  250.                                         else DoUndoTask((*frHndl)->d.doc.root, menuItem - kStdUndo, true);
  251.                                     }
  252.                                     else {
  253.                                         /* Handle rest of edit menu here. */
  254.                                     }
  255.                                 }
  256.                                 break;
  257.                         }
  258.                         break;
  259.                 }
  260.             }
  261.             else SystemEdit(menuItem - 1);
  262.             break;
  263.  
  264.         case mCommunicate:
  265.             switch (menuItem) {
  266.                 case kConnectToUser:
  267.                     DoSetCursor(&qd.arrow);
  268.                     if ((*frHndl)->connect.connected)
  269.                         SendMessage(frHndl, kDisconnectMssg);
  270.                     else
  271.                         SendConnect(frHndl, (char *)"\pDTS.Chat");
  272.                     break;
  273.                 case kSendToUser:
  274.                     SendMessage(frHndl, kStylMssg);
  275.                     SendMessage(frHndl, kTextMssg);
  276.                     break;
  277.  
  278.             }
  279.             break;
  280.  
  281.         case mFonts:
  282.             if (teHndl = CTEFindActive(nil)) {
  283.                 if (menuItem <= kExtend) {
  284.                     if ((*teHndl)->selStart != (*teHndl)->selEnd)
  285.                         CTENewUndo(CTEViewFromTE(teHndl), true);
  286.                     mode = (styl.tsFace = stylVal[menuItem]) ? (doFace | doToggle) : (doFace);
  287.                     TESetStyle(mode, &styl, true, teHndl);
  288.                     CTEAdjustTEBottom(teHndl);
  289.                     CTEAdjustScrollValues(teHndl);
  290.                     SetDocDirty(frHndl);
  291.                 }
  292.                 if (menuItem == kFontSize) {
  293.                     if ((*teHndl)->selStart != (*teHndl)->selEnd)
  294.                         CTENewUndo(CTEViewFromTE(teHndl), true);
  295.                     size = 0;
  296.                     mode = doSize;
  297.                     TEContinuousStyle(&mode, &styl, teHndl);
  298.                     if (mode)
  299.                         if (!(size = styl.tsSize))
  300.                             size = 12;
  301.                     if (styl.tsSize = NewFontSize(size)) {
  302.                         TESetStyle(doSize, &styl, true, teHndl);
  303.                         CTEAdjustTEBottom(teHndl);
  304.                         CTEAdjustScrollValues(teHndl);
  305.                         SetDocDirty(frHndl);
  306.                     }
  307.                 }
  308.                 if (menuItem >= kFirstFont) {
  309.                     if ((*teHndl)->selStart != (*teHndl)->selEnd)
  310.                         CTENewUndo(CTEViewFromTE(teHndl), true);
  311.                     menu = GetMHandle(mFonts);
  312.                     GetItem(menu, menuItem, str);
  313.                     GetFNum(str, &styl.tsFont);
  314.                     TESetStyle(doFont, &styl, true, teHndl);
  315.                     CTEAdjustTEBottom(teHndl);
  316.                     CTEAdjustScrollValues(teHndl);
  317.                     SetDocDirty(frHndl);
  318.                 }
  319.             }
  320.             break;
  321.  
  322.         default:
  323.             handled = false;
  324.             break;
  325.  
  326.     }
  327.  
  328.     return(handled);
  329. }
  330.  
  331.  
  332.  
  333. /*****************************************************************************/
  334.  
  335.  
  336.  
  337. #pragma segment Menu
  338. Boolean    DoAdjustFileMenu(WindowPtr window)
  339. {
  340.     MenuHandle    menu;
  341.     FileRecHndl    frHndl;
  342.     short        enableItem;
  343.  
  344.     menu = GetMHandle(mFile);
  345.     EnableItem(menu, UnmapMItem(mFile, kStdQuit));            /* Gotta be able to quit. */
  346.  
  347.     if (IsDAWindow(window)) {
  348.         EnableItem(menu, UnmapMItem(mFile, kStdClose));        /* Let DAs do a close from the menu. */
  349.         return(false);
  350.     }
  351.  
  352.     if (!gLowOnMem) {
  353.         EnableItem(menu, UnmapMItem(mFile, kStdNew));
  354.         EnableItem(menu, UnmapMItem(mFile, kStdOpen));
  355.     }
  356.  
  357.     if (window = FrontWindowOfType(kwIsDocument, true)) {
  358.         EnableItem(menu, UnmapMItem(mFile, kStdClose));
  359.         frHndl = (FileRecHndl)GetWRefCon(window);
  360.         if ((*frHndl)->fileState.sfType == kDocFileType) {
  361.             enableItem = GetWindowDirty(window);
  362.             if ((*frHndl)->fileState.refNum == kInvalRefNum)
  363.                 enableItem = true;
  364.             if (enableItem)
  365.                 EnableItem(menu, UnmapMItem(mFile, kStdSave));
  366.             EnableItem(menu, UnmapMItem(mFile, kStdSaveAs));
  367.         }
  368.         EnableItem(menu, UnmapMItem(mFile, kDuplicate));
  369.         EnableItem(menu, UnmapMItem(mFile, kStdPageSetup));
  370.         EnableItem(menu, UnmapMItem(mFile, kStdPrint));
  371.     }
  372.  
  373.     return(false);
  374. }
  375.  
  376.  
  377.  
  378. /*****************************************************************************/
  379.  
  380.  
  381.  
  382. #pragma segment Menu
  383. Boolean    DoAdjustEditMenu(WindowPtr window)
  384. {
  385.     MenuHandle        menu;
  386.     Boolean            menuEnabled;
  387.     FileRecHndl        frHndl;
  388.  
  389.     menu = GetMHandle(mEdit);
  390.  
  391.     if (IsDAWindow(window)) {
  392.         EnableItem(menu, UnmapMItem(mEdit, kStdUndo));
  393.         EnableItem(menu, UnmapMItem(mEdit, kStdCut));
  394.         EnableItem(menu, UnmapMItem(mEdit, kStdCopy));
  395.         EnableItem(menu, UnmapMItem(mEdit, kStdPaste));
  396.         EnableItem(menu, UnmapMItem(mEdit, kStdClear));
  397.         return(false);
  398.     }
  399.  
  400.     if (IsAppWindow(window)) {
  401.         frHndl = (FileRecHndl)GetWRefCon(window);
  402.         switch ((*frHndl)->fileState.sfType) {
  403. #if VH_VERSION
  404.             case kViewHierFileType:
  405.                 CTEEditMenu(&menuEnabled, mEdit, UnmapMItem(mEdit, kStdUndo),
  406.                                                  UnmapMItem(mEdit, kStdCut));
  407.                 break;
  408. #endif
  409.             default:
  410.                 EnableItem(menu, UnmapMItem(mEdit, kStdViewHier));
  411.                 CTEEditMenu(&menuEnabled, mEdit, UnmapMItem(mEdit, kStdUndo),
  412.                                                  UnmapMItem(mEdit, kStdCut));
  413.                 break;
  414.         }
  415.     }
  416.  
  417.     return(false);
  418. }
  419.  
  420.  
  421.  
  422. /*****************************************************************************/
  423.  
  424.  
  425.  
  426. #pragma segment Menu
  427. Boolean    DoAdjustCommunicateMenu(WindowPtr window)
  428. {
  429.     MenuHandle        menu;
  430.     FileRecHndl        frHndl;
  431.  
  432.     menu = GetMHandle(mCommunicate);
  433.  
  434.     CheckItem(menu, kConnectToUser, false);
  435.  
  436.     if (IsAppWindow(window)) {
  437.         frHndl = (FileRecHndl)GetWRefCon(window);
  438.         if (!(*frHndl)->fileState.readOnly) {
  439.             if (gHasAppleEvents) {
  440.                 if ((*frHndl)->fileState.sfType == kDocFileType) {
  441.                     EnableItem(menu, kConnectToUser);
  442.                     if ((*frHndl)->connect.connected) {
  443.                         DisableItem(menu, kConnectToUser);
  444.                         EnableItem(menu, kSendToUser);
  445.                     }
  446.                     CheckItem(menu, kConnectToUser, (*frHndl)->connect.connected);
  447.                 }
  448.             }
  449.         }
  450.     }
  451.  
  452.     return(false);
  453. }
  454.  
  455.  
  456.  
  457. /*****************************************************************************/
  458.  
  459.  
  460.  
  461. #pragma segment Menu
  462. Boolean    DoAdjustFontsMenu(WindowPtr window)
  463. {
  464.     MenuHandle        menu;
  465.     FileRecHndl        frHndl;
  466.     TEHandle        teHndl;
  467.     short            i, j, mode, fnum;
  468.     TextStyle        styl;
  469.     Str255            str;
  470.  
  471.     menu = GetMHandle(mFonts);
  472.  
  473.     for (i = CountMItems(menu); i; --i)
  474.         CheckItem(menu, i, false);
  475.  
  476.     if (!IsAppWindow(window))
  477.         return(false);
  478.  
  479.     frHndl = (FileRecHndl)GetWRefCon(window);
  480.     teHndl = CTEFindActive(nil);
  481.     if ((!teHndl) || (teHndl == (*frHndl)->d.doc.inBox))
  482.         return(false);
  483.  
  484.     for (i = CountMItems(menu); i; --i)
  485.         EnableItem(menu, i);
  486.  
  487.     mode = (doFont | doFace);
  488.     styl.tsFace = 0x7F;        /* Check out all styles. */
  489.     TEContinuousStyle(&mode, &styl, teHndl);
  490.     GetFontName(styl.tsFont, str);
  491.     GetFNum(str, &styl.tsFont);
  492.     if (mode & doFace) {
  493.         if (!(j = styl.tsFace))
  494.             CheckItem(menu, kPlain, true);
  495.         else
  496.             for (i = kBold; i <= kExtend; ++i, j >>= 1)
  497.                 if (j & 0x01)
  498.                     CheckItem(menu, i, true);
  499.     }
  500.     if (mode & doFont) {
  501.         for (i = CountMItems(menu); i >= kFirstFont; --i) {
  502.             GetItem(menu, i, str);
  503.             GetFNum(str, &fnum);
  504.             if (fnum == styl.tsFont) {
  505.                 CheckItem(menu, i, true);
  506.                 break;
  507.             }
  508.         }
  509.     }
  510.  
  511.     return(false);
  512. }
  513.  
  514.  
  515.  
  516. /*****************************************************************************/
  517.  
  518.  
  519.  
  520. #pragma segment Menu
  521. static short    NewFontSize(short size)
  522. {
  523.     short        item, itype;
  524.     Handle        ihandle;
  525.     Rect        irect;
  526.     Str255        str;
  527.     WindowPtr    oldPort;
  528.     DialogPtr    dialog;
  529.  
  530.     GetPort(&oldPort);
  531.  
  532.     if (dialog = GetCenteredDialog(rNewFontSizeDlg, nil, FrontWindow(), (WindowPtr)-1L)) {
  533.         SetPort(dialog);
  534.         if (size) {
  535.             GetDItem(dialog, 4, &itype, &ihandle, &irect);
  536.             pcpydec(str, size);
  537.             SetIText(ihandle, str);
  538.             SelIText(dialog, 4, 0, 32767);
  539.         }
  540.         for (size = 0;;) {
  541.             ModalDialog((ModalFilterProcPtr)KeyEquivFilter, &item);
  542.             if (item == 3) break;
  543.             if (item == 1) {
  544.                 GetDItem(dialog, 4, &itype, &ihandle, &irect);
  545.                 GetIText(ihandle, str);
  546.                 size = p2dec(str, nil);
  547.                 if (size < 6)   size = 6;
  548.                 if (size > 128) size = 128;
  549.                 break;
  550.             }
  551.         }
  552.         DisposeDialog(dialog);
  553.     }
  554.  
  555.     SetPort(oldPort);
  556.     return(size);
  557. }
  558.  
  559.  
  560.  
  561.